<template>

  <div class="start-only-office">
    <div v-if="edit&&!hasDocument">
      <start-new-office @openDocument="openNewDocument"></start-new-office>
    </div>
    <div v-if="!edit&&!hasDocument">
      <el-empty :description="emptyText"/>
    </div>
    <div class="header-right" v-if="showOffice">
      <el-icon size="18" style="margin-top: 6px" @click="toggleFullScreen">
        <FullScreen/>
      </el-icon>
    </div>
    <start-new-office-dialog ref="startNewOfficeDialog" @openDocument="openNewDocument"></start-new-office-dialog>
    <div class="content" :id="officeId"></div>
  </div>


</template>

<script>
import {defineComponent} from 'vue';
import startOfficeApi from "@/api/start/startOfficeApi";
import {deepMerge, loadScriptTag} from "components/start-components/start-office/utils";
import StartNewOffice from "components/start-components/start-office/startNewOffice.vue";
import StartNewOfficeDialog from "components/start-components/start-office/startNewOfficeDialog.vue";

const scriptJsId = "start-only-officeJs"
export default defineComponent({
  name: 'start-office',
  components: {StartNewOfficeDialog, StartNewOffice},
  computed: {
    hasDocument() {
      if (this.modelValue === null) {
        return false;
      }
      return this.modelValue.length > 0;
    },
    officeId() {
      return "onlyOfficeEditor_" + Math.random()
    },
  },
  props: {
    emptyText: {
      type: String,
      default: "无文档"
    },

    accept: {
      type: String,
      default: ".doc,.docx,.xls,.xlsx,.ppt,.pptx"
    },
    tip: {
      type: String,
      default: null,
    },
    fileSize: {
      type: [Number, String],
      default: "10MB"
    },
    modelValue: {
      type: String,
      default: null,
    },
    edit: {
      type: [String, Boolean],
      default: true
    },
    document_fileType: String,
    document_title: String,
    documentType: String,
    editorConfig_lang: String,
    onLoadComponentError: Function,
    events_onAppReady: Function,
    events_onDocumentStateChange: Function,
    events_onMetaChange: Function,
    events_onDocumentReady: Function,
    events_onInfo: Function,
    events_onWarning: Function,
    events_onError: Function,
    events_onRequestSharingSettings: Function,
    events_onRequestRename: Function,
    events_onMakeActionLink: Function,
    events_onRequestInsertImage: Function,
    events_onRequestSaveAs: Function,
    events_onRequestEditRights: Function,
    events_onRequestHistory: Function,
    events_onRequestHistoryClose: Function,
    events_onRequestHistoryData: Function,
    events_onRequestRestore: Function,
    events_onRequestSelectSpreadsheet: Function,
    events_onRequestSelectDocument: Function,
    documentConfig: {
      type: Object,
      default: () => {
        return {}
      }
    },
  },
  watch: {

    documentConfig: {
      handler: function (newVal, oldVal) {
        this.onChangeProps();
      },
      deep: true
    },
    modelValue: function (newVal, oldVal) {
      this.loadOssDocumentConfig();
    },
    document_fileType: function (newVal, oldVal) {
      this.onChangeProps();
    },
    document_title: function (newVal, oldVal) {
      this.onChangeProps();
    },
    documentType: function (newVal, oldVal) {
      this.onChangeProps();
    },
    editorConfig_lang: function (newVal, oldVal) {
      this.onChangeProps();
    },
    height: function (newVal, oldVal) {
      this.onChangeProps();
    },
    type: function (newVal, oldVal) {
      this.onChangeProps();
    },
    width: function (newVal, oldVal) {
      this.onChangeProps();
    }
  },
  data() {
    return {
      showOffice: false,
      eventsConfigOnRequestClose: null,
      docConfig: null,
      officeConnector: null,
      docEditorInstances: null,
    }
  },
  created() {
    let config = this.documentConfig;
    if (!config.events) {
      config.events = {};
    }
    this.eventsConfigOnRequestClose = config.events.onRequestClose
    config.events.onRequestClose = this.onRequestClose;
    this.docConfig = config;
  },
  mounted() {
    this.loadOssDocumentConfig()
  },
  methods: {
    openNewDocument(ossId, done) {
      this.destroyEditor()
      this.$emit('update:modelValue', ossId);
      if (done) {
        done()
      }
      this.showOffice = false;
    },

    toggleFullScreen() {
      let element = this.$el
      if (document.fullscreenElement || document.msFullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement ? true : false) {
        if (document.exitFullscreen) {
          document.exitFullscreen();
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen();
        } else if (document.webkitCancelFullScreen) {
          document.webkitCancelFullScreen();
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen();
        }
      } else {
        if (element.requestFullscreen) {
          element.requestFullscreen();
        }/*FireFox */ else if (element.mozRequestFullScreen) {
          element.mozRequestFullScreen();
        }/*Chrome等 */ else if (element.webkitRequestFullScreen) {
          element.webkitRequestFullScreen();
        }/*IE11*/ else if (element.msRequestFullscreen) {
          element.msRequestFullscreen();
        }

      }
    },

    loadOssDocumentConfig() {
      console.log("加载文档", this.modelValue)
      if (!this.modelValue) {
        return
      }
      let documentConfig = {};
      documentConfig.type = "desktop"
      documentConfig.lang = 'zh'
      documentConfig.canEdit = this.edit;
      this.showOffice = false;
      startOfficeApi.getDocumentConfigByOssId(this.modelValue, documentConfig).then(res => {
        this.docConfig = res.data.data;
        let url = this.docConfig.officeRootUrl;
        if (!url.endsWith("/")) {
          url += "/";
        }
        url = "".concat(url, "web-apps/apps/api/documents/api.js");
        return loadScriptTag(scriptJsId, url)
      }).then(res => {
        this.showOffice = true
        this.onLoad()
      }).catch(err => {
        console.log(err)
        this.$message.error(err)
      })
    },
    onLoad() {
      const id = this.officeId;
      if (!window.DocsAPI) {
        this.onError(-3);
        return;
      }
      const docEditor = window.DocEditor || (window.DocEditor = {instances: {}});
      if (docEditor.instances[id]) {
        console.log("Skip loading. Instance already exists", id);
        return;
      }
      let initConfig = {}
      initConfig.document = {
        fileType: this.document_fileType,
        title: this.document_title,
      }
      initConfig.documentType = this.documentType;
      initConfig.editorConfig = {
        lang: this.editorConfig_lang,
      };
      initConfig.events = {}
      initConfig.events.onAppReady = this.onAppReady
      initConfig.events.onDocumentStateChange = this.events_onDocumentStateChange
      initConfig.events.onMetaChange = this.events_onMetaChange
      initConfig.events.onDocumentReady = this.onDocumentReady
      initConfig.events.onInfo = this.events_onInfo
      initConfig.events.onWarning = this.events_onWarning
      initConfig.events.onError = this.events_onError
      initConfig.events.onRequestSharingSettings = this.events_onRequestSharingSettings
      initConfig.events.onRequestRename = this.events_onRequestRename
      initConfig.events.onMakeActionLink = this.events_onMakeActionLink
      initConfig.events.onRequestInsertImage = this.events_onRequestInsertImage
      initConfig.events.onRequestSaveAs = this.events_onRequestSaveAs
      initConfig.events.onRequestEditRights = this.events_onRequestEditRights
      initConfig.events.onRequestHistory = this.events_onRequestHistory
      initConfig.events.onRequestHistoryClose = this.events_onRequestHistoryClose
      initConfig.events.onRequestHistoryData = this.events_onRequestHistoryData
      initConfig.events.onRequestRestore = this.events_onRequestRestore
      initConfig.events.onRequestSelectSpreadsheet = this.events_onRequestSelectSpreadsheet
      initConfig.events.onRequestSelectDocument = this.events_onRequestSelectDocument
      initConfig.events.onRequestCreateNew = this.onRequestCreateNew
      initConfig.height = "100%";
      initConfig.type = this.type;
      initConfig.width = "100%";
      let config = deepMerge({}, initConfig, this.docConfig)
      try {
        docEditor.instances[id] = window.DocsAPI.DocEditor(id, config);
      } catch (err) {
        console.error(err);
        this.onError(-1);
      }
    },


    onError(errorCode) {
      let message;
      switch (errorCode) {
        case -2:
          message = "Error load DocsAPI from " + this.docConfig.officeRootUrl;
          break;
        case -3:
          message = "DocsAPI is not defined";
          break;
        default:
          message = "Unknown error loading component";
          errorCode = -1;
      }
      if (typeof this.onLoadComponentError == "undefined") {
        console.error(message);
      } else {
        this.onLoadComponentError(errorCode, message);
      }
    },
    onAppReady() {
      this.events_onAppReady(window.DocEditor.instances[this.officeId]);
    },
    onChangeProps() {
      if (window?.DocEditor?.instances[id]) {
        window.DocEditor.instances[id].destroyEditor();
        window.DocEditor.instances[id] = undefined;
        console.log("Important props have been changed. Load new Editor.");
        this.onLoad();
      }
    },

    onRequestCreateNew() {
      this.$refs.startNewOfficeDialog.show()
    },
    onRequestClose() {
      if (this.eventsConfigOnRequestClose) {
        this.eventsConfigOnRequestClose(window.DocEditor.instances[this.officeId])
      }
    },
    onDocumentReady() {
      console.log("文档加载成功")

      let docEditorInstances = window.DocEditor.instances[this.officeId];
      this.docEditorInstances = docEditorInstances
      console.log("this.docEditorInstances", this.docEditorInstances)
      if (this.events_onDocumentReady) {
        this.events_onDocumentReady()
      }
      try {
        this.officeConnector = docEditorInstances.createConnector();
      } catch (e) {
        console.error(e)
      }


      // console.debug("connector", this.officeConnector);
      //
      // var items = [
      //   {
      //     "id": "onConvert",
      //     "text": getMessage("Convert to Markdown or HTML")
      //   }
      // ];
      //
      // this.officeConnector.addContextMenuItem(items);
      //

      console.log("Document is loaded");
    },
    onLoadComponentError(errorCode, errorDescription) {
      switch (errorCode) {
        case -1: // Unknown error loading component
          console.log(errorDescription);
          break;

        case -2: // Error load DocsAPI from http://documentserver/
          console.log(errorDescription);
          break;

        case -3: // DocsAPI is not defined
          console.log(errorDescription);
          break;
      }
    },
    destroyEditor() {
      if (this.officeConnector) {
        this.officeConnector = null;
      }
      const docEditor = window.DocEditor || (window.DocEditor = {instances: {}});
      if (this.docEditorInstances) {
        this.docEditorInstances.requestClose();
        this.docEditorInstances.destroyEditor();
        this.docEditorInstances = null;
        docEditor.instances[this.officeId] = null;
        console.log("this.docEditorInstances.destroyEditor")
      }
    }
  },
  beforeUnmount() {
    this.destroyEditor()

  }
});
</script>
<style lang="scss">
@use "start-only-office";
</style>
